
//
// 给定一个含有n个正整数的数组和一个正整数 target 。
// 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组[numsl, numsl+1, ..., numsr-1, numsr] ，并返回其长度。如果不存在符合条件的子数组，返回 0 。
// 来源：力扣（LeetCode）
// 链接：https://leetcode-cn.com/problems/minimum-size-subarray-sum
//     著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
// 算法：双指针
// 思路：
// 1. 初始化两个指针，一个指向数组的开头，一个指向数组的结尾。
// 2. 当前指针的值与目标值的和，如果大于目标值，则将开头指针向右移动一位，直到和小于目标值。
// 3. 当前指针的值与目标值的和，如果小于目标值，则将结尾指针向左移动一位，直到和大于目标值。
// 4. 如果开头指针和结尾指针相同，则返回0。
// 5. 如果开头指针和结尾指针不相同，则返回结尾指针减去开头指针+1的值。

// var minSubArrayLen = function (target, nums) {
//   let left = 0;
//   let right = 0;
//   let sum = 0;
//   let min = Infinity;
//   while (right < nums.length) {
//     sum += nums[right];   // 当前子数组的和
//     while (sum >= target) { // 当前子数组的和大于 target，则将指针向左移动一位。
//       min = Math.min(min, right - left + 1);    // 更新最小值
//       sum -= nums[left];                       // 当前子数组的和减去左边的数字
//       left++;
//     }
//     right++;
//   }
//   return min === Infinity ? 0 : min;  // 如果没有找到，则返回 0
//
// }
// 滑动窗口
// 先是 fast 往后遍历并加上遍历过的数值，即让滑动窗口右边界不断扩充
// 当总和大于 target 时，slow 开始动，收缩滑动窗口左边界，并减去对应值，直到总和小于 target，开始寻找下一个滑动窗口
// 重复 1 和 2 步骤
var minSubArrayLen = function (target, nums) {
    let left = 0;
    let right = 0;
    let sum = 0;
    let res = Infinity;
    while (right < nums.length) {
        sum = sum + nums[right];    // 当前子数组的和
        while (sum >= target) {
            res = Math.min(res, right - left + 1);
            sum = sum - nums[left]; //! 让窗口动起来
            left++;
        }
        right++;
    }
    return res;
}
console.log(minSubArrayLen(7, [2, 3, 1, 2, 4, 3]));